#pragma once

#include <vector>
#include "scr_resource_manager.h"
#include "scr_enemy.h"
#include "scr_enemy_behavior_blinky.h"
#include "scr_enemy_behavior_pinky.h"
#include "scr_enemy_behavior_inky.h"
#include "scr_powerup.h"

#define SCR_MAP_SIZE_X 2048
#define SCR_MAP_SIZE_Y 2048
#define SCR_MAP_GRID_SHIFT_X 3
#define SCR_MAP_GRID_SHIFT_Y 3
#define SCR_MAP_GRID_SIZE_X (SCR_MAP_SIZE_X >> SCR_MAP_GRID_SHIFT_X)
#define SCR_MAP_GRID_SIZE_Y (SCR_MAP_SIZE_Y >> SCR_MAP_GRID_SHIFT_Y)
#define SCR_MAP_GRID_COUNT_X ((SCR_MAP_SIZE_X) / SCR_MAP_GRID_SIZE_X)
#define SCR_MAP_GRID_COUNT_Y ((SCR_MAP_SIZE_Y) / SCR_MAP_GRID_SIZE_Y)
#define SCR_BLOCK_COUNT 20
#define SCR_BLOCK_GRID_COUNT_X 64
#define SCR_BLOCK_GRID_COUNT_Y 64
#define SCR_ENEMY_COUNT 1000
#define SCR_POWERUP_COUNT 3

class SCRMarine;
class SCRBasicSprite;
class SCRProjectile;

typedef std::shared_ptr<SCRProjectile> SCRProjectilePtr;

struct SCRGameData
{
	SCRGameData();
	~SCRGameData();
	void ClearBuckets();
	void CreateMarine(SCRTexturePtr TextureTop, SCRTexturePtr TextureBottom);
	SCRMarine* GetMarine() const;
	void CreateEnemy(SCRTexturePtr Texture);
	SCRBasicSprite* GetEnemy() const;
	void AddToBucket(const int& ObjectIndex, const int& PositionX, const int& PositionY);
	void GenerateBlocks(SCRTexturePtr TextureTarget, SCRTexturePtr TextureBlocks);
	void ClearCheckMap();
	void InitializeEnemies();
	void UpdateEnemies(const int& Delta);
	void RenderEnemies(const int& Delta);
	void UpdateProjectiles(const int& Delta);
	void RenderProjectiles(const int& Delta);
	void FireProjectile(const FX32& Angle, const FX32& Speed, const int& Lifetime, const int& Damage);
	int UpdatePowerUps(const int& Delta);
	void RenderPowerUps(const int& Delta);

	std::vector<int> m_Buckets[SCR_MAP_GRID_COUNT_X][SCR_MAP_GRID_COUNT_Y];
	int m_MapBlocksAA[SCR_BLOCK_GRID_COUNT_X][SCR_BLOCK_GRID_COUNT_Y];
	int m_CheckMapAA[SCR_BLOCK_GRID_COUNT_X][SCR_BLOCK_GRID_COUNT_Y];
	SCREnemy m_EnemiesA[SCR_ENEMY_COUNT];
	SCREnemyBehaviorBlinky m_Blinky;
	SCREnemyBehaviorPinky m_Pinky;
	SCREnemyBehaviorInky m_Inky;
	SCRTexturePtr m_ProjectileTexture;
	std::vector<SCRProjectilePtr> m_Projectiles;
	SCRPowerUp m_PowerUpA[SCR_POWERUP_COUNT];
	int m_PowerUpIndex;
	SCRTexturePtr m_PowerUpTexture;
	SCRTexturePtr m_BloodTexture;
	SCRTexturePtr m_Background;

private:

	SCRMarine* m_pMarine;
	SCRBasicSprite* m_pEnemy;
	SCRBasicSprite* m_pPowerUp;
};

inline SCRMarine* SCRGameData::GetMarine() const
{
	return m_pMarine;
}

inline SCRBasicSprite* SCRGameData::GetEnemy() const
{
	return m_pEnemy;
}
